package com.drifter;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TiledMapTileSet;

import java.util.HashMap;

public class DrifterMain extends ApplicationAdapter {
    // The batch process.
	private SpriteBatch batch;

    // The game camera.
    private OrthographicCamera camera;

    // The game map.
    private Map map;

    // The size of the tile textures.
    private int tileSize = 32;

    // Place the textures into a hashmap.
    private HashMap<Map.TileEnum, Texture> tileEnumToTextureMap;

    // The player.
    private EntityPlayer player;
    private TiledMapTileSet tiledMapTileSet;
    private Texture playerTexture;

    // In charge of updating the game.
    private Driver driver;

    // Smaller number is faster gameplay.
    private long gameSpeed = 50;
    private long lastUpdate = 0;

    private int lastKeypress;

    @Override
	public void create () {
        this.batch = new SpriteBatch();
        this.playerTexture = new Texture("Adventurer_(Cleric).png");
        //this.tiledMapTileSet = new TiledMapTileSet();
        this.camera = new OrthographicCamera();
        this.camera.setToOrtho(false, 1440, 900);

        // Generate the map.
        MapGen mapGen = new MapGen();
        this.map = mapGen.generateMap();

        // Generate the player.
        this.player = new EntityPlayer(this.map, this.map.getSpawn());

        // Generate the driver.
        this.driver = new Driver(this.map, this.player);

        populateTileEnumToTextureMap();
	}

    public void populateTileEnumToTextureMap ( ) {
        this.tileEnumToTextureMap = new HashMap<Map.TileEnum, Texture>();
        this.tileEnumToTextureMap.put(Map.TileEnum.EMPTY, new Texture("EmptyTile32.png"));
        this.tileEnumToTextureMap.put(Map.TileEnum.GRASS, new Texture("GrassTile32.png"));
        this.tileEnumToTextureMap.put(Map.TileEnum.MARTIANSOIL, new Texture("MartianSoil32.png"));
    }

	@Override
	public void render () {
        // Clear the screen.
        Gdx.gl.glClearColor(0.25f, 0.65f, 0.95f, 0.1f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        // Camera follows the player.
        this.camera.position.set(this.player.getX() * this.tileSize, this.player.getY() * this.tileSize, 0);
        this.camera.update();

        // Paint the world.
        this.batch.setProjectionMatrix(this.camera.combined);
        MapCell center = this.player.getPosition();
        int horizontalTileRadius = Math.round(this.camera.viewportWidth / 2 / this.tileSize);
        int verticalTileRadius = Math.round(this.camera.viewportHeight / 2 / this.tileSize);
        this.batch.begin();
        for (int x = center.getX() - horizontalTileRadius; x < center.getX() + horizontalTileRadius; x++) {
            for (int y = center.getY() - verticalTileRadius; y < center.getY() + verticalTileRadius; y++) {
                if (this.map.getMapCell(x, y) == null) {
                    continue;
                }
                Map.TileEnum tileType = this.map.getMapCell(x, y).getTileType();
                if (this.tileEnumToTextureMap.containsKey(tileType)) {
                    this.batch.draw(this.tileEnumToTextureMap.get(tileType), x * this.tileSize, y * this.tileSize);
                }
            }
        }
        this.batch.draw(this.playerTexture, this.player.getPosition().getX() * this.tileSize, this.player.getPosition().getY() * this.tileSize);
        this.batch.end();

        if (Gdx.input.isKeyPressed(Input.Keys.A)) {
            this.lastKeypress = Input.Keys.A;
        } else if (Gdx.input.isKeyPressed(Input.Keys.D)) {
            this.lastKeypress = Input.Keys.D;
        } else if (Gdx.input. isKeyPressed(Input.Keys.S)) {
            this.lastKeypress = Input.Keys.S;
        } else if (Gdx.input.isKeyPressed(Input.Keys.W)) {
            this.lastKeypress = Input.Keys.W;
        }

        // Call driver if enough time has passed.
        if (System.currentTimeMillis() - this.gameSpeed > this.lastUpdate) {
            this.lastUpdate = System.currentTimeMillis();
            if (this.lastKeypress != 0) {
                this.driver.drive(this.lastKeypress);
            }

            this.lastKeypress = 0;
        }
	}
}
